#include <iostream>
#include <regex>
#include <string>
//坑：g++版本过低，正则表达式报错，语法完全支持，但是库还没跟上，所以编译的时候是没有问题的，但是一运行就会直接抛出异常

//"GET /bitejiuyeke?a=b&c=d HTTP/1.1\r\n"

using std::string;
using std::cout;
using std::endl;

//获取请求方法
void MethodMatch(const string& str)
{
    std::smatch sm;
    std::regex e ("(GET|HEAD|POST|PUT|DELETE).*");
    std::regex_match(str, sm, e);
    //cout << sm.size() << endl;
    for(int i = 0; i < sm.size(); i++)
    {
        cout << sm[i] << endl;
    }
    cout << "---------------------------" << endl;
}

//获取资源路径
void PathMatch(const string& str)
{
    std::smatch sm;
    std::regex e ("([^?]+).*");
    std::regex_match(str, sm, e);
    for(int i = 0; i < sm.size(); i++)
    {
        cout << sm[i] << endl;
    }
    cout << "---------------------------" << endl;
}

//获取查询信息
//?:\\?，因为?:表示匹配但不提取，所以整体需放在括号里
void QueryMatch(const string& str)
{
    std::smatch sm;
    //"(?:\\?(.*?))? .*"
    //"^([^ ]+)"
    std::regex e ("(?:\\?(.*?))? .*");    //细节：结合测试用例，空格要加上；查询字符串后的空格及后面的内容需要被匹配但不用提取！
    //std::regex e ("^([^ ]+).*");
    std::regex_match(str, sm, e);
    for(int i = 0; i < sm.size(); i++)
    {
        cout << sm[i] << endl;
    }
    cout << "---------------------------" << endl;
}

//获取版本信息
//[]是用于匹配字符的，无法匹配\n or \r
void VersionMatch(const string& str)
{ 
    std::smatch sm;
    std::regex e ("(HTTP/1\\.[0|1])(?:\n|\r\n)");
    std::regex_match(str, sm, e);
    for(int i = 0; i < sm.size(); i++)
    {
        cout << sm[i] << endl;
    }
    cout << "---------------------------" << endl;
}

int main()
{
    //注意这里测试时不能将整个请求作为参数，正则表达式在匹配时会有异常；需单独分配测试的字符串！
    MethodMatch("GET /s");
    PathMatch("/bitejiuyeke?a=b&c=d");
    //QueryMatch("?a=b&c=d HTTP/1.1\r\n");      坑：注意，最后带/r/n了！！！故一直匹配失败
    QueryMatch("?name=xiaoming&age=19 HTTP/1.1");
    VersionMatch("HTTP/1.1\r\n");
    return 0;
}